/**


 */
package org.mybatis.generator.codegen.mybatis3.model;

import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.codegen.AbstractJavaGenerator;

import java.util.ArrayList;
import java.util.List;


public class ControllerGenerator extends AbstractJavaGenerator {

    public ControllerGenerator() {
        super();
    }

    private Field getControllerBaseFile() {

        Field field = new Field(
                introspectedTable.getDomainFirstNameLowerCase() + "ServiceImpl",
                new FullyQualifiedJavaType(introspectedTable.
                        getDomianName() + "Service")
        );

        field.setVisibility(JavaVisibility.PRIVATE);
        field.addAnnotation("@Autowired");

        return field;
    }

    public List<Method> getControllerBaseMethod(String serviceName) {

        List<Method> list = new ArrayList<Method>();

        list.add(getDeleteMethod(serviceName));
        list.add(getInsertMethod(serviceName));
        list.add(getSelectMethod(serviceName));
        list.add(getUpdateMethod(serviceName));

        return list;
    }

    private Method getSelectMethod(String serviceName) {

        StringBuilder sb = new StringBuilder();
        sb.insert(0, "List<").append(introspectedTable.getDomianName()).append(">");

        return getBaseMethod(
                serviceName,
                introspectedTable.getSelectByPrimaryKeyStatementId(),
                new FullyQualifiedJavaType(sb.toString())
        );
    }

    private Method getInsertMethod(String serviceName) {
        return getBaseMethod(
                serviceName,
                introspectedTable.getInsertSelectiveStatementId(),
                FullyQualifiedJavaType.getStringInstance()
        );
    }

    private Method getUpdateMethod(String serviceName) {

        return getBaseMethod(
                serviceName,
                introspectedTable.getUpdateByPrimaryKeySelectiveStatementId(),
                FullyQualifiedJavaType.getStringInstance()
        );
    }


    private Method getDeleteMethod(String serviceName) {

        return getBaseMethod(
                serviceName,
                introspectedTable.getDeleteByPrimaryKeyStatementId(),
                FullyQualifiedJavaType.getStringInstance()
                );
    }

    private Method getBaseMethod(
                        String serviceName,
                        String typeName,
                        FullyQualifiedJavaType returnTypeName
                        ) {

        StringBuilder sb = new StringBuilder();
        sb.append(typeName);
        Method method = new Method(sb.toString());
        sb
                .insert(0, "@RequestMapping(value = \"/")
                .append(".dom\", method = RequestMethod.POST)");
        method.addAnnotation(sb.toString());

        sb.setLength(0);
        sb.append("@ResponseBody");
        method.addAnnotation(sb.toString());
        method.setVisibility(JavaVisibility.PUBLIC);

        sb.setLength(0);
        method.setReturnType(returnTypeName);
        method.addParameter(new Parameter(
                new FullyQualifiedJavaType(introspectedTable.
                        getDomianName()),
                introspectedTable.getDomainFirstNameLowerCase()
        ));

        sb.setLength(0);
        sb
                .insert(0, "return " + serviceName)
                .append(".")
                .append(typeName)
                .append("(")
                .append(introspectedTable.getDomainFirstNameLowerCase())
                .append(");");
        method.addBodyLine(sb.toString());

        return method;


    }


    @Override
    public List<CompilationUnit> getCompilationUnits() {

        TopLevelClass topLevelClass = createTopLevelClass();
        topLevelClassInitClass(topLevelClass);
        topLevelClassInitType(topLevelClass);
        Field f = getControllerBaseFile();
        topLevelClass.addField(f);
        List<Method> list = topLevelClass.getMethods();
        list.addAll(getControllerBaseMethod(f.getName()));


        List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
        answer.add(topLevelClass);
        return answer;
    }


    private TopLevelClass createTopLevelClass() {

        FullyQualifiedJavaType type = new FullyQualifiedJavaType(
                introspectedTable.getControllerType());

        return new TopLevelClass(type);
    }

    /**
     * 初始化TopLevelClass的Class
     *
     * @param topLevelClass
     */
    private void topLevelClassInitClass(TopLevelClass topLevelClass) {
        StringBuilder sb = new StringBuilder();
        sb.append("@Controller");
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.addAnnotation(sb.toString());
        sb.setLength(0);
        sb.append("@RequestMapping(\"/");
        sb.append(introspectedTable.getDomainFirstNameLowerCase());
        sb.append("\")");
        topLevelClass.addAnnotation(sb.toString());

    }

    /**
     * 初始化TopLevelClass的Type
     *
     * @param topLevelClass
     */
    private void topLevelClassInitType(TopLevelClass topLevelClass) {
        String mapperPathName = introspectedTable.getMyBatis3XmlMapperPackage();
        String basePathName = mapperPathName.substring(0, mapperPathName.lastIndexOf("."));
        String servicePackage = basePathName + ".service." +
                introspectedTable.getDomianName() + "Service";

        topLevelClass.addImportedType(servicePackage);
        topLevelClass.addImportedType(introspectedTable.getBaseRecordType());
        addDefaultTypeForControllerAndService(topLevelClass);

    }

}
